package com.yunji.storage.business;

import com.yunji.base.domain.BelongDO;
import com.yunji.base.event.GuavaEventBus;
import com.yunji.cabinet.vo.CellProductCountVO;
import com.yunji.common.base.BaseBusiness;
import com.yunji.common.constant.LogicCode;
import com.yunji.common.enums.common.ErrorEnum;
import com.yunji.common.enums.common.UserType;
import com.yunji.common.event.notice.StockWarmNoticeEvent;
import com.yunji.common.model.dto.LoginInfo;
import com.yunji.common.utils.ConvertDataUtil;
import com.yunji.common.utils.DecimalUtils;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.storage.bo.StockListQueryBO;
import com.yunji.storage.consumer.StockConsumer;
import com.yunji.storage.domain.StockDO;
import com.yunji.storage.service.IStockService;
import com.yunji.system.context.SystemContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Project: yunji-coffee
 * @Package: com.yunji.storage.business
 * @Title: StockBusiness
 * <p>
 * History:
 * Date                     Version     Author          Summary
 * ============================================================
 * 2024-08-15 15:59:18      V1.0        HuaAo       新建类
 */
@Service
public class StockBusiness extends BaseBusiness {

    @Resource
    IStockService stockService;

    @Resource
    StockConsumer stockConsumer;

    private static final String MESSAGE = "{}的{}商品库存已达预警值";

    /**
     * @param stockId   库存ID
     * @param warmValue 预警值
     * @Title setWarmValue
     * @Desc 设置预警值
     * @Date 2024-08-31 17:03:10.131
     */
    @Transactional
    public void setWarmValue(Long stockId, BigDecimal warmValue) {
        //Assert.isTrue(DecimalUtils.more(warmValue,BigDecimal.ZERO),"预警值不能小于零");

        // 查出原本的信息
        StockDO vo = stockService.select(stockId);
        Assert.isTrue(BeanUtils.isNotNull(vo), ErrorEnum.BUSINESS_812010.getText());

        BigDecimal usableStock = vo.getUsableStock();
        logs.info("【设置预警值】可用库存:{}", usableStock);

        // 发送预警消息
        if (DecimalUtils.more(warmValue, usableStock)) {
            LoginInfo loginInfo = SystemContext.getUser();
            loginInfo.setBelongId(vo.getBelongId());
            GuavaEventBus.post(new StockWarmNoticeEvent(loginInfo, vo.getProductId()));
        }

        StockDO update = new StockDO();
        update.setStockId(stockId);
        update.setWarmValue(warmValue);
        Assert.isTrue(stockService.update(update), "修改失败");
    }

    /**
     * @param belongId
     * @param stockStatus
     * @Title operateStock
     * @Desc 操作库存开关
     * @Date 2024-10-24 18:42:39.211
     */
    public void operateStock(Long belongId, Integer stockStatus) {
        LoginInfo user = SystemContext.getUser();
        String userType = user.getUserType();
        Assert.isTrue(Objects.equals(UserType.PLATE.getCode(), userType), "用户无权操作");

        // 找到网点的每个在售商品的数量  比较之前的占用库存

        // 查看当前所属的占用库存
        List<StockDO> stockVOList = stockService.search(new StockListQueryBO(belongId));
        Map<Long, StockDO> stockVOMap = ConvertDataUtil.list2Map(stockVOList, StockDO::getProductId);

        List<StockDO> createList = new ArrayList<>();
        List<StockDO> updateList = new ArrayList<>();

        List<CellProductCountVO> voList = stockConsumer.countCellProduct(belongId);
        Map<Long, CellProductCountVO> countVOMap = ConvertDataUtil.list2Map(voList, CellProductCountVO::getProductId);
        if (BeanUtils.isNotNull(voList) && Objects.equals(LogicCode.YES, stockStatus)) {

            // 新增、更新占用库存
            for (CellProductCountVO cellVO : voList) {
                StockDO stock = new StockDO();
                Long productId = cellVO.getProductId();
                BigDecimal frozenStock = cellVO.getNums();
                stock.setBelongId(belongId);
                stock.setProductId(productId);
                stock.setAllStock(BigDecimal.ZERO);
                stock.setDisableStock(BigDecimal.ZERO);
                if (stockVOMap.containsKey(productId)) {
                    StockDO vo = stockVOMap.get(productId);
                    frozenStock = cellVO.getNums().subtract(vo.getFrozenStock());
                    stock.setFrozenStock(frozenStock);
                    stock.setUsableStock(frozenStock.negate());
                    updateList.add(stock);
                } else {
                    stock.setFrozenStock(frozenStock);
                    stock.setUsableStock(frozenStock.negate());
                    createList.add(stock);
                }
            }

            // 退还占用库存
            for (StockDO vo : stockVOList) {
                if (!countVOMap.containsKey(vo.getProductId())) {
                    StockDO stock = new StockDO();

                    BigDecimal frozenStock = vo.getFrozenStock();
                    stock.setProductId(vo.getProductId());
                    stock.setBelongId(belongId);
                    stock.setFrozenStock(frozenStock.negate());
                    stock.setUsableStock(frozenStock);
                    stock.setDisableStock(BigDecimal.ZERO);
                    stock.setAllStock(BigDecimal.ZERO);
                    updateList.add(stock);
                }
            }

        } else if (BeanUtils.isNotNull(stockVOList) && Objects.equals(LogicCode.YES, stockStatus)) {
            for (StockDO vo : stockVOList) {
                if (!countVOMap.containsKey(vo.getProductId())) {
                    StockDO stock = new StockDO();
                    if (DecimalUtils.more(vo.getFrozenStock())) {
                        BigDecimal frozenStock = vo.getFrozenStock();
                        stock.setProductId(vo.getProductId());
                        stock.setBelongId(belongId);
                        stock.setFrozenStock(frozenStock.negate());
                        stock.setUsableStock(frozenStock);
                        stock.setDisableStock(BigDecimal.ZERO);
                        stock.setAllStock(BigDecimal.ZERO);
                        updateList.add(stock);
                    }
                }
            }
        }

        for (StockDO create : createList) {
            Assert.isTrue(stockService.create(create), "新增失败");
        }

        for (StockDO update : updateList) {
            Assert.isTrue(stockService.updateStock(update), "修改失败");
        }

        BelongDO update = new BelongDO();
        update.setBelongId(belongId);
        update.setStockStatus(stockStatus);
        stockConsumer.updateBelong(update);
    }

    /**
     * @param ids
     * @Title remove
     * @Desc 删除库存
     * @Date 2024-10-25 16:30:47.528
     */
    @Transactional
    public void deleteEmptyStock(Long... ids) {
        stockService.deleteEmptyStock(ids);
    }

    /*---------------------------------------校验----------------------------------------*/

    /**
     * @param param
     * @Title handleParam
     * @Desc 补充查询参数
     * @Date 2024-09-14 10:18:32.344
     */
//    public void handleParam(StockParam param) {
//        LoginInfo user = tokenService.getUser();
//        String userType = user.getUserType();
//        Long belongId = user.getBelongId();
//        logs.info("【库存列表】用户类型:{},所属ID:{}", userType, belongId);
//        if (Objects.equals(RoleTypes.AGENT.getCode(), userType)) {
//            param.setParentId(belongId);
//        }
//        if (Objects.equals(RoleTypes.SITE.getCode(), userType)) {
//            param.setBelongId(belongId);
//        }
//    }


}
